<!DOCTYPE html>
<html lang="en">
<head>
  <title>关于Lisp采用波兰式的一些想法</title>
  <meta charset="UTF-8">
  <meta name="description" content="ltoddy's blog">
  <meta name="author" content="liutao">
  <meta name="author" content="ltoddy">
  <meta name="author" content="just for fun">

  <link rel="stylesheet" href="../../static/css/bootstrap.css">
  <link rel="stylesheet" href="../../static/css/bootstrap-theme.css">
  <link rel="icon" href="../../static/me.jpg">

  <script src="../../static/js/jquery-3.2.1.min.js"></script>
  <script src="../../static/js/bootstrap.js"></script>
</head>
<body>
<a href="https://github.com/ltoddy/ltoddy.github.io" target="_blank"><img
    style="position: absolute; top: 0; right: 0; border: 0;"
    src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67"
    alt="Fork me on GitHub"
    data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png">
</a>
<div class="container">
  <div class="page-header">
    <h3>关于Lisp采用波兰式的一些想法</h3>
  </div>
  <p>我并没有去专门为了Lisp使用前缀表达式而去网上寻找鼓吹有关此方面的文章或书籍。我也并不是Lisp的狂热爱好者。学习Lisp最初只不过是学习其伟大思想。
    不过当我慢慢学过Lisp一段时间之后，我慢慢的发自内心的喜欢上了它。我用的是Scheme，一个教学用的语言。当然对于其使用的前缀表达式我也想说一下我自己的认识。</p>
  <p>先说一点：前缀表达式也可以叫波兰式，后缀表达式也可以叫逆波兰式。</p>
  <p>上过数据结构课，我们都知道前缀、中缀和后缀表达式分别对应的表达式树的先序、中序和后续遍历。也就是说前缀、中缀和后缀表达式这三者可以互相转换的。</p>
  <p>
    <small>比如：</small>
  </p>
  <ul>
    <li>中缀：1 + 2 + (3 + 4) * 5 + 6 + 7</li>
    <li>后缀：1 2 + 3 4 + 5 * + 6 + 7 +</li>
    <li>前缀：+ + + + 1 2 * + 3 4 5 6 7</li>
  </ul>
  <p>很多人是很不适应甚至反感前缀表达式的，因为很不习惯，我们从小学习数学，学习基本的四则运算，好像数学都是用的中缀表达式。真的是这样子吗！</p>
  <p>其实不是的，在四则运算加减乘除以外的世界，其实都是用的前缀表达式，举个例子，比如根号√4，这是在数学再常见不过的求根表达式了。它就是一个前缀表达式。
    根号在最前面。当然根号是个一元运算符，根号里面的被视为一个整体，对整体求值。</p>
  <p>在举一个例子，比如令许多人头疼的积分∫。它也是前缀表达式，积分符号∫在各个参数的最前面。 </p>
  <p>现在看来，数学书上就是在用前缀表达式，大家也都可以适应，为什么到了编程中就不怎么适应了……</p>
  <hr>
  <p>当然更坑爹的是逆波兰式：比如Pascal中定义变量var x : real;
    或者近来的年度语言Golang的定义变量var x float。(顺便说一句，之前看过王垠的博客，它也不喜欢go的这种定义变量方法)
    大家习惯的是比如double x;这样子的定义变量方法。</p>
  <p>当然有些时候，在处理二元关系的时候，无论是波兰式还是逆波兰式都没有中缀表达式好理解。就比如我们的四则运算，只不过是把加减乘除当作了特殊的运算法。
    也就是只能处理二元关系的运算符(这里的是减号而不是负号--一元运算符)。</p>
  <p>除此之外呢，比如函数f(x . y)，这个样子写是表示函数f中可以有多个参数。也就是C语言中的f(int... a)可变参数。</p>
  <p>如果我们把函数f当作是一个运算符，其实它可以是运算符或者是它就是运算符，因为它处理了参数。函数就是一个采用前缀的表达方法。</p>
  <p>因为如果你不用前缀你怎么写出表达式呢？比如要定义x，y，z这三个参数的和的函数，sum(x, y, z)，如果用中缀你如何写出表达式呢？
    (x sum y) sum z 这个样子吗？这个样子好像也停坑爹的。也就是说前缀可以支持任意多的参数，而中缀只能支持两个。因为到了多元关系之后，中缀几乎不存在
    这样的表示方法，根本没有可比较的对象。</p>
  <p>所以当处理非二元关系的时候，前缀表达式还是有一些优越的。另一点，如果这个operator的名字比较长，放在前面会好看一些。(窃喜</p>
  <p>当然使用前缀表达式可以与函数表示方法相统一。这个样子，就可以使得很多事情变得和谐，统一。</p>
  <p>说了这些，其实前缀中缀最大的分歧在于二元关系上，如果二元关系出现的多，那就使用中缀表达式，如果多元关系出现的多那就使用波兰式。</p>
</div>

</body>
</html>